package org.semanticflash.rdf.graph
{
	import com.bigflexlib.ds.container.zet.IOSet;
	import com.bigflexlib.ds.container.zet.IOWSet;
	import com.bigflexlib.ds.container.zet.impl.owSet;
	
	import org.semanticflash.rdf.triple.IRDFTripleProvider;
	import org.semanticflash.rdf.triple.RDFTriple;

	
	
	
		
	
	/**
	 * 
	 * 
	 * This base class exists merely to split concerns.
	 * We take care of the truth logic.
	 * our subclass takes care of redirection
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */	
	public class RDFStatementBase
	{
		
		
		///////////////////////////////////////////////////
		// triple 
		///////////////////////////////////////////////////

		protected var _triple:RDFTriple;
		/**
		 * 
		 * The explicitly stated triple
		 * 
		 * @return 
		 * 
		 */		
		public function get triple():RDFTriple
		{
			return _triple;
		}
		
		
		
		///////////////////////////////////////////////////
		// graph 
		///////////////////////////////////////////////////
	
		protected var graph:RDFGraph;
		
		
		
		
		///////////////////////////////////////////////////
		// sources 
		///////////////////////////////////////////////////
		
		private var _sources:IOWSet;
		/**
		 * 
		 * The sources that support this statement
		 * 
		 * @return 
		 * 
		 */	
		public function get sources( ):IOSet { return _sources; }
	
		
		
		
		///////////////////////////////////////////////////
		// isTrue 
		///////////////////////////////////////////////////		
		
		
		protected var _isTrue:Boolean = false;
		/**
		 * 
		 * A statement is true when there are sources to support it
		 * 
		 * 
		 * @return 
		 * 
		 */		
		public function get isTrue( ):Boolean
		{
			return _isTrue;				
		}

		
		
		
		public function RDFStatementBase( triple:RDFTriple, graph:RDFGraph )
		{
			
			_triple = triple;			
			
			this.graph = graph;

			_sources = owSet( );		
			
		}
		
		
		
		
		/**
		 * 
		 * This is a hook for our subclass
		 * 
		 * @param newIsTrue
		 * 
		 */				
		protected function setIsTrue( newIsTrue:Boolean ):void
		{
			_isTrue = newIsTrue;
		}
		
		
		
		
		
		
		
		
		
		///////////////////////////////////////////////////////////////////////
		// sources 
		///////////////////////////////////////////////////////////////////////
		
		
		public function addSource( source:IRDFTripleProvider ):void
		{
			modSource( source, true );
		}
		
		
		public function removeSource( source:IRDFTripleProvider ):void
		{
			modSource( source, false );
		}		


		// we use this instead of an event listener because its faster
		private function modSource( source:IRDFTripleProvider, add:Boolean ):void
		{
			
			if ( add )
				_sources.add( source );
			else
				_sources.remove( source );
			
			
			
			var newIsTrue:Boolean = _sources.size > 0;
			
			if ( newIsTrue != _isTrue )
			{
				setIsTrue( newIsTrue );			
			}
				
		}		
		
		
		
		
		
		
		
		
		
		
		
		
		
		

	}
}